from google.appengine.api.urlfetch import fetch , GET , POST , DELETE
from com.google.code.zkit.twitter.oauth.Oauth import quote 
from com.google.code.zkit.twitter.ProxyHandler import ProxyHandler
from com.google.code.zkit.twitter.oauth.Config import MemcacheConfig
from com.google.code.zkit.twitter.oauth.OauthHeaderBuilder import OauthHeaderBuilder
import base64
import hashlib
import logging
from com.google.code.zkit.twitter.VerifyCredentialsProxy import VerifyCredentialsProxy
from com.google.code.zkit.twitter.oauth.UserIdentify import UserIdentify

# proxy apis
class RestApiProxy(ProxyHandler): 
    
    # overide this method to get proxied api server url
    def getApiServer(self):
        return "";
 
    # pre-set http oauth headers
    def buildHeader(self, method, parameters):
        # need authorize 
        if "Authorization" in self.request.headers and "oauth" not in self.request.headers["Authorization"].lower():
            logging.debug("Authorization introspection ,Authorization: %s" % self.request.headers["Authorization"])
            basic_authorize_info = base64.b64decode(self.request.headers["Authorization"].replace("Basic", "").replace("relm", "").replace(" " , ""))
            logging.debug("basic_authorize_info : %s" % basic_authorize_info)
            pair = basic_authorize_info.split(":")
            user = self.getUser(pair[0], pair[1])
            if user is not None:
                oauth_paramters = {"oauth_token":user.oauth_token}
                oauth_paramters.update(parameters)
                self.request.headers.update(
                                            OauthHeaderBuilder.buildHeaderByDict(
                                                                                 "%s%s" % (
                                                                                         self.getApiServer() ,
                                                                                         self.request.path.replace("/twitter/", "")
                                                                                         ),
                                                                                 method,
                                                                                 user.oauth_token_secret,
                                                                                 oauth_paramters
                                                                                 )
                                            )
                
    def getUser(self, name, password):
        user = self.client.get(name, MemcacheConfig.user_cache_namespace)
        if user is None:
            logging.debug("user %s not in memcache , try from db" % name)
            user = UserIdentify.get_by_key_name(name)
            if user is None:
                logging.debug("user %s not in db , try authorize" % name)
                VerifyCredentialsProxy.doAuthorize(name, password)
                user = self.client.get(name, MemcacheConfig.user_cache_namespace)
            else:
                logging.debug("cache user %s" % name)
                self.client.set(name, user , namespace=MemcacheConfig.user_cache_namespace)
            
        if user is not None:
            logging.debug("retrieve user %s done" % name)
            if user.password == hashlib.md5(password).hexdigest():
                logging.debug("password match , saved password %s" % user.password)
                return user
            else:
                logging.debug("password not match , saved password %s" % user.password)
                return None
        else:
            logging.debug("can`t not retrieve user %s" % name)
            return None
            
    # just forward request , replacing original host
    def proxy(self , method , *args):
        logging.debug("request url: %s%s?%s , header: %s , query_string: %s , body: %s" % (
                                            self.getApiServer() ,
                                            self.request.path.replace("/twitter/", "").lower(),
                                            self.request.query_string,
                                            self.request.headers,
                                            self.request.query_string,
                                            self.request.body)
                                            )
        # do api proxy
        response = fetch(
                            "%s%s?%s" % (
                                            self.getApiServer() ,
                                            self.request.path.replace("/twitter/", "").lower(),
                                            self.request.query_string
                                        ),
                            self.request.body,
                            method,
                            self.request.headers,
                        )
        # loging job
        logging.debug("header = %s , respondse = %s" % (response.headers, response.content))
        self.response.headers = response.headers 
        self.response.out.write(response.content)
        
    # handle http get   
    def get(self, *args):
        parameters = self.convertParameters(self.request.query_string)
        self.buildHeader("GET", parameters)
        self.request.query_string = "&".join("%s=%s" % (quote(key) , quote(value)) for key, value in parameters.items())
        self.proxy(GET, *args)
        
    # handle http post
    def post(self, *args):
        parameters = self.convertParameters(self.request.body)
        self.buildHeader("POST", parameters)
        self.request.body = "&".join("%s=%s" % (quote(key) , quote(value)) for key, value in parameters.items())
        self.proxy(POST, *args)
    
    # handle http delete   
    def delete(self , *arps):
        self.buildHeader("DELETE", None)
        self.proxy(DELETE, *arps)
